﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;

using eBookDomain;
using eBookDataAccess;

using ClipMon.Win32;
using EPocalipse.IFilter;
using eBook.Core;
using eBook.Core.BusinessObjects;

namespace eBookWinApp
{
  public partial class frmRenamer : Form
  {
    private IntPtr _clipboardViewerNext;
    private Process _readerProcess = null;
    private BookRenamer _renamer;
        
    // subversion hosting
    // https://code.google.com/hosting/settings


    #region Clipboard Hook 
    
    private void RegisterClipboardViewer()
    {
      _clipboardViewerNext = User32.SetClipboardViewer( this.Handle );
    }

    private void UnregisterClipboardViewer()
    {
      User32.ChangeClipboardChain( this.Handle, _clipboardViewerNext );
    }

    private void GetClipboardData()
    {
      Application.DoEvents();
      IDataObject iData = Clipboard.GetDataObject();
      if ( iData.GetDataPresent( DataFormats.Text ) )
      {
        string clpContent = ( string ) iData.GetData( DataFormats.Text );
        FetchClipboardText( clpContent );    
        Search();
      }
    }

    private void FetchClipboardText( string clpContent )
    { 
      bool isbnValid = false;
      if ( new ISBN10( clpContent ).Validate() )
      {
        isbnValid = true;
        txtISBN10.Text = clpContent;
      }
        
      if ( new ISBN13( clpContent ).Validate() )
      {
        txtISBN13.Text = clpContent;
        isbnValid = true;
      }

      if (isbnValid)
        MinimizeReaderProcess();

      Application.DoEvents();
    }

    protected override void WndProc( ref Message m )
    {
      switch ( ( Msgs ) m.Msg )
      {
        //
        // The WM_DRAWCLIPBOARD message is sent to the first window 
        // in the clipboard viewer chain when the content of the 
        // clipboard changes. This enables a clipboard viewer 
        // window to display the new content of the clipboard. 
        //
        case Msgs.WM_DRAWCLIPBOARD:

          Debug.WriteLine( "WindowProc DRAWCLIPBOARD: " + m.Msg, "WndProc" );

          GetClipboardData();

          //
          // Each window that receives the WM_DRAWCLIPBOARD message 
          // must call the SendMessage function to pass the message 
          // on to the next window in the clipboard viewer chain.
          //
          User32.SendMessage( _clipboardViewerNext, m.Msg, m.WParam, m.LParam );
          break;


        //
        // The WM_CHANGECBCHAIN message is sent to the first window 
        // in the clipboard viewer chain when a window is being 
        // removed from the chain. 
        //
        case Msgs.WM_CHANGECBCHAIN:
          Debug.WriteLine( "WM_CHANGECBCHAIN: lParam: " + m.LParam, "WndProc" );

          // When a clipboard viewer window receives the WM_CHANGECBCHAIN message, 
          // it should call the SendMessage function to pass the message to the 
          // next window in the chain, unless the next window is the window 
          // being removed. In this case, the clipboard viewer should save 
          // the handle specified by the lParam parameter as the next window in the chain. 

          //
          // wParam is the Handle to the window being removed from 
          // the clipboard viewer chain 
          // lParam is the Handle to the next window in the chain 
          // following the window being removed. 
          if ( m.WParam == _clipboardViewerNext )
          {
            //
            // If wParam is the next clipboard viewer then it
            // is being removed so update pointer to the next
            // window in the clipboard chain
            //
            _clipboardViewerNext = m.LParam;
          }
          else
          {
            User32.SendMessage( _clipboardViewerNext, m.Msg, m.WParam, m.LParam );
          }
          break;

        default:
          //
          // Let the form process the messages that we are
          // not interested in
          //
          base.WndProc( ref m );
          break;

      }

    } 
    
    #endregion
    
    public frmRenamer()
    {
      InitializeComponent();
      InitializeForm();
    }

    private void InitializeForm()
    {
      ResetGUI();

      txtISBN10.KeyUp += new KeyEventHandler( OnKeyUpHandler );
      txtISBN13.KeyUp += new KeyEventHandler( OnKeyUpHandler );
      
      _renamer = new BookRenamer();
      _renamer.LibraryBaseFolder = @"E:\eBookRoot\eBookLibrary";      
      //_renamer.LibraryBaseFolder = @"F:\Downloads\BufferZone";

      txtOpFolder.Text = _renamer.LibraryBaseFolder;
    }

    private void frmRenamer_Load( object sender, EventArgs e )
    {
      RegisterClipboardViewer();
    }




    private void frmRenamer_FormClosing( object sender, FormClosingEventArgs e )
    {
      UnregisterClipboardViewer();
      
      txtISBN10.KeyUp -= new KeyEventHandler( OnKeyUpHandler );
      txtISBN13.KeyUp -= new KeyEventHandler( OnKeyUpHandler );
      
      KillReaderProcess(); 
    }

    private void btnOpen_Click( object sender, EventArgs e )
    {
      if ( dlgOpen.ShowDialog() == DialogResult.OK)
      {
        txtFilename.Text = dlgOpen.FileName;
        FileOpen(dlgOpen.FileName); 
      }
    }
        
    private void btnSearch_Click( object sender, EventArgs e )
    {
      Application.DoEvents();          
      Search();
    }

    private void Search()
    {
      Application.DoEvents();     
      
      ISBN isbn = null;
      if ( !string.IsNullOrEmpty( txtISBN10.Text ) )
        isbn = new ISBN10( txtISBN10.Text );
      else if ( !string.IsNullOrEmpty( txtISBN13.Text ) )
        isbn = new ISBN13( txtISBN13.Text );

      if ( isbn == null || !isbn.Validate() )
        return;  
        
      SearchWithISBN(isbn);      
    }
    
    private void SearchWithISBN(ISBN isbn)
    {
      if ( isbn == null )
        return;    

      try
      {
        Cursor.Current = Cursors.WaitCursor;
        _renamer.SourceFilePath = txtFilename.Text;
        boBookInfo searchResult = _renamer.Search( isbn );
        if ( searchResult != null )
        {
          txtTitle.Text = searchResult.Title;
          txtAuthors.Lines = searchResult.Authors;
          txtNewFileName.Text = _renamer.DestinationFilePath;

          if ( !string.IsNullOrEmpty( searchResult.MediumImageURL ) )
            //imgBook.Image = ( System.Drawing.Image ) Utils.DownloadWebResource( searchResult.MediumImageURL );
            imgBook.LoadAsync( searchResult.MediumImageURL );            
        }
      }
      catch ( Exception exception )
      {
        MessageBox.Show( string.Format( "{0}\n{1}"
                                      , isbn
                                      , exception.Message) );
      }
      finally
      {
        Cursor.Current = Cursors.Default;
      }
    }

    private void btnRename_Click( object sender, EventArgs e )
    {
      KillReaderProcess(); 
      
      if ( !string.IsNullOrEmpty(txtNewFileName.Text) )
      {      
        _renamer.SourceFilePath = txtFilename.Text;
        _renamer.DestinationFilePath = txtNewFileName.Text;
        _renamer.Rename();        
      }  
    }
    
    private void btnExtract_Click( object sender, EventArgs e )
    {
      KillReaderProcess();      
      //txtFileContent.Text = ExtractFileContent(txtFilename.Text);
      txtFileContent.Lines = ExtractFileContent();
    }
    
    private void FileOpen(string sourceFileName)
    {
      ResetGUI();
      KillReaderProcess();              
      
      _readerProcess = new Process();
      ProcessStartInfo si = new ProcessStartInfo("\"" + sourceFileName + "\"");
      
      si.CreateNoWindow = false;

      _readerProcess.StartInfo = si;
      _readerProcess.Start();

      return ;
    }

    private void KillReaderProcess()
    {
      if ( _readerProcess != null )
      {
        try
        {
          //_readerProcess.CloseMainWindow();
          //_readerProcess.Kill();
          //_readerProcess.Close();
          
          User32.SendMessage(_readerProcess.MainWindowHandle, (int) ClipMon.Win32.Msgs.WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
          _readerProcess.Dispose();
        }
        catch ( Exception ex )
        {
          MessageBox.Show( ex.GetType().ToString() );
        }
        //System.Threading.Thread.Sleep(1000);
        _readerProcess = null;        
      }
    }
    
    private void MinimizeReaderProcess()
    { 
      const int SC_MINIMIZE = 61472;                            
      //User32.SendMessage( _readerProcess.MainWindowHandle, (int) Msgs.WM_ACTIVATE, IntPtr.Zero, IntPtr.Zero);
      //User32.SendMessage(_readerProcess.MainWindowHandle, (int) Msgs.WM_SYSCOMMAND, (IntPtr) SC_MINIMIZE, IntPtr.Zero);

      if (_readerProcess == null)
        return;

      User32.PostMessage( _readerProcess.MainWindowHandle, (uint) Msgs.WM_ACTIVATE, IntPtr.Zero, 0);
      User32.PostMessage(_readerProcess.MainWindowHandle, (uint) Msgs.WM_SYSCOMMAND, (IntPtr) SC_MINIMIZE, 0);

    }

    private void ResetGUI()
    {
      txtISBN10.Clear();
      txtISBN13.Clear();
      txtTitle.Clear();
      txtAuthors.Clear();
      txtNewFileName.Clear();
      txtFileContent.Clear();
      imgBook.Image = null;
      Clipboard.Clear();
    }
    
    private void OnKeyUpHandler( object sender, KeyEventArgs e )
    {
      if (e.KeyCode == Keys.Return)
        if ( (sender is Control) && !string.IsNullOrEmpty( (sender as Control).Text ) )
          Search();
    }


    private string[] ExtractFileContent()
    {
      LuceneIndexer ind = new LuceneIndexer();
      ind.Index();
      

      return ind.Search("some");      
    }
    
    
    private string ExtractFileContentEX(string fileName)
    {
      string fileContent = string.Empty;
      char[] tBuf = new char[8192];

      try
      {
        using ( TextReader reader = new FilterReader(fileName) )
        {
          //if (_readToEnd)
          //  fileContent = reader.ReadToEnd();
          //else
          //{
            reader.ReadBlock(tBuf, 0, 4096);
            fileContent = (new StringBuilder().Append(tBuf)).ToString();
          //}
        }
      }
      catch (Exception ex)
      {
        MessageBox.Show("Can not extract text! " + ex.Message);
      }
      
      return fileContent;      
    }




      
  }
}
